package com.apobates.jforum.grief.aurl.utils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Optional;

public class DateTimeUtils {
    /**
     * 将字符串按指定格式解析
     * @param value 字符串
     * @param format 日期格式
     * @return 解析失败返回当前实例: LocalDateTime.now()
     */
    public static LocalDateTime parse(String value, String format){
        try {
            return LocalDateTime.parse(value, DateTimeFormatter.ofPattern(format));
        }catch (Exception e){
            return LocalDateTime.now();
        }
    }

    /**
     * 将字符串按指定格式解析
     * @param value 字符串
     * @param format 日期格式
     * @return 解析失败返回当前实例: Optional.empty
     */
    public static Optional<LocalDateTime> of(String value, String format){
        try {
            LocalDateTime parse = LocalDateTime.parse(value, DateTimeFormatter.ofPattern(format));
            return Optional.ofNullable(parse);
        }catch (Exception e){
            return Optional.empty();
        }
    }

    /**
     * 判断指定的参数是未来时
     * @param dateTime 若为null返回false
     * @return 在参数可用时且相比现在是未来时间返回true
     */
    public static boolean isFuture(LocalDateTime dateTime){
        if(dateTime==null){
            return false;
        }
        // 以分钟计
        LocalDateTime now = LocalDateTime.now();
        return dateTime.isBefore(LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), now.getHour(), now.getMinute()));
    }

    /**
     * 判断指定的参数是未来时
     * @param date 若为null返回false
     * @return 在参数可用时且相比现在是未来时间返回true
     */
    public static boolean isFuture(LocalDate date){
        if(date==null){
            return false;
        }
        // 以天计
        LocalDate now = LocalDate.now();
        return date.isBefore(LocalDate.of(now.getYear(), now.getMonth(), now.getDayOfMonth()));
    }

    /**
     * 判断指定的参数是未来时
     * 注意: 使用系统当前所在的时区
     * @param zonedDateTime 若为null返回false
     * @return 在参数可用时且相比现在是未来时间返回true
     */
    public static boolean isFuture(ZonedDateTime zonedDateTime){
        if(zonedDateTime==null){
            return false;
        }
        // 以分钟计
        ZonedDateTime now = ZonedDateTime.now();
        LocalDateTime datetime = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), now.getHour(), now.getMinute());
        return zonedDateTime.isBefore(ZonedDateTime.of(datetime, ZoneId.systemDefault()));
    }

    /**
     * 判断指定的参数是未来时
     * 注意: 使用系统当前所在的时区
     * @param instant 若为null返回false
     * @return 在参数可用时且相比现在是未来时间返回true
     */
    public static boolean isFuture(Instant instant){
        if(instant==null){
            return false;
        }
        return instant.isBefore(ZonedDateTime.now().toInstant());
    }

    /**
     * 判断指定的参数是过去时
     * @param dateTime 若为null返回true
     * @return 相比现在是过去时间或参数不可用返回true
     */
    public static boolean isPast(LocalDateTime dateTime){
        if(dateTime==null){
            return true;
        }
        // 以分钟计
        LocalDateTime now = LocalDateTime.now();
        return dateTime.isAfter(LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), now.getHour(), now.getMinute()));
    }

    /**
     * 判断指定的参数是过去时
     * @param date 若为null返回true
     * @return 相比现在是过去时间或参数不可用返回true
     */
    public static boolean isPast(LocalDate date){
        if(date==null){
            return true;
        }
        // 以分钟计
        LocalDate now = LocalDate.now();
        return date.isAfter(LocalDate.of(now.getYear(), now.getMonth(), now.getDayOfMonth()));
    }

    /**
     * 判断指定的参数是过去时
     * 注意: 使用系统当前所在的时区
     * @param zonedDateTime 若为null返回true
     * @return 相比现在是过去时间或参数不可用返回true
     */
    public static boolean isPast(ZonedDateTime zonedDateTime){
        if(zonedDateTime==null){
            return true;
        }
        // 以分钟计
        ZonedDateTime now = ZonedDateTime.now();
        LocalDateTime datetime = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), now.getHour(), now.getMinute());
        return zonedDateTime.isAfter(ZonedDateTime.of(datetime, ZoneId.systemDefault()));
    }

    /**
     * 判断指定的参数是过去时
     * 注意: 使用系统当前所在的时区
     * @param instant 若为null返回true
     * @return 相比现在是过去时间或参数不可用返回true
     */
    public static boolean isPast(Instant instant){
        if(instant==null){
            return true;
        }
        return instant.isAfter(ZonedDateTime.now().toInstant());
    }
}
